﻿using System;
using System.Collections.Generic;
using PasswordControl.Core.Data;
using System.Windows.Input;
using PasswordControl.UI.WPF.ViewModel.PasswordPackage;
using System.Windows.Media;
using System.IO;
using Infrastructure.Diagnostics;
using PasswordControl.UI.WPF.Data;

namespace PasswordControl.UI.WPF.ViewModel.PackageProvider
{
    class PackageProviderViewModel : ViewModelBase
    {
        private string m_packagePath;
        private IPasswordPackage m_package;

        private string m_message;
        private Brush m_messageColor;

        #region Properties

        public string Password { private get; set; }

        public string PackagePath
        {
            set { m_packagePath = value; OnPropertyChanged(o => (o as PackageProviderViewModel).PackagePath); }
            get { return m_packagePath; }
        }

        public PasswordPackageViewModel CurrentPackage
        {
            get { return (m_package == null) ? null : new PasswordPackageViewModel(m_package); }
        }

        #endregion

        #region Provider message

        public string PackageProviderMessage 
        {
            get { return m_message; }
            private set
            {
                m_message = value;
                OnPropertyChanged(o => (o as PackageProviderViewModel).PackageProviderMessage);
            }
        }

        public Brush PackageProviderMessageColor
        {
            get { return m_messageColor; }
            private set
            {
                m_messageColor = value;
                OnPropertyChanged(o => (o as PackageProviderViewModel).PackageProviderMessageColor);
            }
        }

        #endregion

        #region Commands

        public ICommand LoadPackageCommand
        {
            get { return new LoadPackageCommand(this); }
        }

        public ICommand StorePackageCommand
        {
            get { return new StorePackageCommand(this); }
        }

        public ICommand CreatePackageCommand
        {
            get { return new CreatePackageCommand(this); }
        }

        #endregion

        #region constructor

        public PackageProviderViewModel()
        {
            CreatePackage();
        }

        #endregion

        #region Command implementations

        public void LoadPackage()
        {
            if (!ValidateInputs()) return;

            try 
            { 
                m_package = PasswordControl.Core.Data.PackageProvider.GetPackage(PackagePath, Password);
                UserData.Instance.LastComponentPath = PackagePath;
            }
            catch (Exception e) 
            {
                Logger.Warning("Failed to load package. {0}", e.ToString());
                m_package = null; 
            }

            if (m_package == null) SetErrorMessage("Password is not correct or file format is invalid");
            else SetConfirmMessage("Package loaded");
            
            OnPropertyChanged(o => (o as PackageProviderViewModel).CurrentPackage);
        }

        public void StorePackage()
        {
            if (!ValidateInputs()) return;
            PasswordControl.Core.Data.PackageProvider.StorePackage(PackagePath, Password, m_package);
            SetConfirmMessage("Package saved");
        }

        public void CreatePackage()
        {
            m_package = PasswordControl.Core.Data.PackageProvider.CreatePackage();
            OnPropertyChanged(o => (o as PackageProviderViewModel).CurrentPackage);
        }

        #endregion

        #region Input validation

        private bool ValidateInputs()
        {
            List<string> errors = new List<string>();
            
            if (string.IsNullOrEmpty(Password))
            {
                errors.Add("Password is missing");
            }

            if (string.IsNullOrEmpty(PackagePath))
            {
                errors.Add("Package path is missing");
            }
            else if (!File.Exists(PackagePath))
            {
                errors.Add("Package file doesn't exist");
            }

            if (errors.Count == 0) return true;

            SetErrorMessage(string.Join("\n", errors.ToArray()));
            return false;
        }

        private void SetErrorMessage(string message)
        {
            PackageProviderMessage = message;
            PackageProviderMessageColor = Brushes.Red;
        }

        private void SetConfirmMessage(string message)
        {
            PackageProviderMessage = message;
            PackageProviderMessageColor = Brushes.Black;
        }

        #endregion
    }
}
